package cate.game.role.farm.guildBoss;

import cate.common.table.d.GDFight;
import cate.common.table.d.GDFunc;
import cate.common.table.d.GDGuild;
import cate.common.table.d.GDNotice;
import cate.common.table.guild.guildboss.GuildBossCombatRow;
import cate.common.util.GameResult;
import cate.game.attr.FightAttr;
import cate.game.chat.ChatFacade;
import cate.game.play.part.FightSide;
import cate.game.play.proce.play.PlayPO;
import cate.game.role.Role;
import cate.game.role.farm.AbstractFarm;
import cate.game.role.farm.PlayTimes;
import cate.game.role.farm.guildBoss.msg.MyGuildBossDataResp;
import cate.game.role.fight.FuncPosition;
import cate.game.role.fight.Position;
import cate.game.role.res.guild.boss.msg.GuildBossDataResp;
import cate.game.role.res.guild.po.GuildPO;
import com.fasterxml.jackson.annotation.JsonProperty;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.util.HashMap;
import java.util.Map;

@NoteClass(value = "farm之公会boss")
public class MyGuildBossPO extends AbstractFarm {

    @NoteField(value = "今日de挑战次数记录")
    public PlayTimes playTimes;

    @NoteField(value = "上次打的是第几关的boss", detail = "只有上次打的关数与当前boss的关数相同，才能扫荡")
    public int lastCombatNum;

    @NoteField(value = "上次伤害值", detail = "只有上次打的关数与当前boss的关数相同，才能扫荡，这个值才有意义")
    public long lastDamage;

    @NoteField(value = "上次发送集结号角的时间")
    public long lastHornTime;

    @NoteField(value = "今日点赞记录", detail = "Map<被点赞的主角唯一ID，是否点过它>")
    public Map<String, Boolean> likeRecord;

    @NoteField(value = "领过的boss击杀奖励记录", detail = "Map<关卡id，是否领过>")
    public Map<Integer, Boolean> rankRewardRecord;

    /**
     * "排行榜排名"
     */
    @JsonProperty("rank")
    public int getRank() {
        if (this.role == null) {
            return GDGuild.boss.RANK_NONE_INDEX;
        }
        GuildPO guild = this.role.getRes().guild.getGuild();
        if (guild == null) {
            return GDGuild.boss.RANK_NONE_INDEX;
        }
        return guild.boss.rank.getIndex(this.role.getUid());
    }

    /**
     * 查看是否领取过排行榜奖励
     */
    public boolean checkRankReward(int combatNum) {
        Boolean got = rankRewardRecord.get(combatNum);
        if (got == null) {
            rankRewardRecord.put(combatNum, true);
            return false;
        }
        return true;
    }

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (playTimes == null) {
            playTimes = new PlayTimes();
        }
        playTimes.initialize();
        if (likeRecord == null) {
            likeRecord = new HashMap<>();
        }
        if (rankRewardRecord == null) {
            rankRewardRecord = new HashMap<>();
        }
    }

    @Override
    public int getFightFuncId() {
        return GDFunc.GuildFunc.BOSS;
    }

    public void onDaySpan() {
        playTimes.reset();
        likeRecord.clear();
        role.sendNow(new MyGuildBossDataResp(role));
    }

    /**
     * 挑战
     *
     * @param mop 是否扫荡
     */
    public GameResult<Void> challenge(boolean mop) {
        GameResult<Void> r = new GameResult<>();
        GuildPO guild = role.getRes().guild.getGuild();
        if (guild == null) {
            role.getGame().notice.message(role ,"你还没加入协会");
            return r.fail("你还没加入协会");
        }
        if (fighting){
            role.getGame().notice.message(role,"正在战斗中");
            return r.fail("正在战斗中");
        }

        r = guild.boss.prepare(role);
        if (!r.ok()) {
            return r;
        }
        int combatNumTarget = guild.boss.combatNumPass + 1;
        GuildBossCombatRow tpl = role.getGame().table.guildBoss.combat.get(combatNumTarget);
        if (tpl == null) {
            return r.fail("配置异常");
        }
        GameResult<Void> checkRes = this.playTimes.available(role, getFightFuncId());
        if (!checkRes.ok()) {
            role.getGame().notice.message(role, "道具不足");
            return checkRes;
        }
        if (!mop) {
            //手动
            EcResult<FightSide> fsr = role.getGame().fight.side.createFightSideByCode(GDFight.Team.B, tpl.bossInstanceId);
            if (!fsr.ok()) {
                return r.fail(fsr.message);
            }
            GuildBossFTC context = new GuildBossFTC(role, tpl);

            context.funcId = GDFunc.GuildFunc.BOSS;
            context.setPositionApply(GDFunc.ADVENTURE);
            context.param.sideB.hpExtend.recordByHeroTid(fsr.data.ps.hs.get(0).hero.tid, guild.boss.curHp / (double) tpl.bossHp);

            FightAttr attr = new FightAttr();
            double addedPower = GDGuild.BUFF_AR * guild.boss.buffNum;
            attr.attAR(addedPower);
            context.param.sideA.attrAppend.addTeamAttr(attr);

            context.playStory.level = tpl.id;

            checkPosition();
            EcResult<PlayPO> fightRes = role.getGame().play.startByRole(role, context, fsr.data);

            if (!fightRes.ok()) {
                return r.fail(fightRes.message);
            } else {
                lastCombatNum = tpl.combatNum;
                lastDamage = GuildBossTools.calcDamage(fightRes.data);
            }
            this.fighting = true;
        } else {
            // 扫荡模式
            if (lastCombatNum < tpl.combatNum) {
                role.getGame().notice.message(role ,"请先挑战之后再扫荡");
                return r.fail("请先挑战之后再扫荡");
            }
            if (lastDamage <= 0) {
                role.getGame().notice.message(role ,"请先挑战之后再扫荡");
                return r.fail("请先挑战之后再扫荡");
            }

            GuildBossTools.handleResult(role, lastDamage, tpl, mop);
        }

        // 更新公会表现里挑战次数
        role.getRes().guild.getMember().performance.playTimes = this.playTimes;

        // 记录公会活跃
        role.getRes().guild.active.addActive(GDGuild.activeTask.FIGHT_BOSS);
        role.getHistory().action.challengeGuildBoss();
        return r.success();
    }

    private void checkPosition() {
        Position position = role.getFight().getPosition(GDFunc.GuildFunc.BOSS);
        if (position != null) {
            FuncPosition funcPosition = new FuncPosition();
            funcPosition.init();
            funcPosition.funcId = getFightFuncId();
            funcPosition.positions.add(position.copy());
            role.getGame().fight.position.updatePosition(role, funcPosition);
        }
    }

    /**
     * 发送集结号角
     */
    public GameResult<Void> horn() {
        GameResult<Void> checkRes = role.getRes().guild.checkGuild();
        if (!checkRes.ok()) {
            return checkRes;
        }
        GameResult<Void> r = new GameResult<>();
        if (role.getRes().guild.getPos() == GDGuild.position.MEMBER) {
            role.getGame().notice.message(role, "只有会长和副会长以及长老才能发布集结令");
            return r.fail("只有会长和副会长以及长老才能发布集结令");
        }
        long now = System.currentTimeMillis();
        if (now - lastHornTime < GDGuild.boss.HORN_INTERVAL) {
            long seconds = (GDGuild.boss.HORN_INTERVAL - (now - lastHornTime)) / 1000;
            role.getGame().notice.message(role , String.format("歇息片刻，请%d秒之后再尝试吧", seconds));
            return r.fail("歇息片刻，请" + seconds + "秒之后再尝试吧");
        }
        ChatFacade.sendGuildAsMemberId(role, GDNotice.TextId.GUILD_BOSS_HORN);
        lastHornTime = now;
        //
        noticeUpdate();
        role.sendNow(new GuildBossDataResp(role.getRes().guild.getGuild().boss));
        role.getGame().notice.message(role, "已吹响集结号角");

        return r.success("已吹响集结号角");
    }

    /**
     * 退出公会时清理数据
     */
    public void clear() {
        lastCombatNum = 0;
        lastDamage = 0;
        lastHornTime = 0;
        likeRecord.clear();
    }

    public void noticeUpdate() {
        role.sendNow(new MyGuildBossDataResp(role));
    }

    @Override
    public int getFuncId() {
        return GDFunc.GuildFunc.BOSS;
    }

    @Override
    public void onAfterOpen() {

    }

}
